local M = {}

function M.newWeakRefTable()
	local t = {}

	local t1 = {__mode = "kv"}

	setmetatable(t, t1)
	return t
end

--[[深拷贝
	暂时不考虑key为table的情况
	不考虑value为 userData的情况
]]
function M.deepCopy(tSource, tDest)
	if type(tSource) ~= "table" then
		return nil
	end

	local tDest = tDest or {}

	for key, value in pairs(tSource) do
		if type(value) == "table" then
			print(key, value)

			tDest[key] = {}
			deepCopy(value, tDest[key])
		else
			tDest[key] = value
		end
	end

	return tDest
end

-- todo 这边没有做深拷贝等问题的考虑
function M.setMeta(tOri, tMeta)
	if type(tOri) ~= "table" or type(tMeta) ~= "table" then
		return
	end
	local oriMeta = getmetatable(tOri)


	if oriMeta then
		local metaIndex = oriMeta.__idnex
		tOri.__index = function(t, key)
			if type(metaIndex) == "function" then
				return metaIndex(t, key) or tMeta[key]
			elseif type(metaIndex) == "table" then
				return metaIndex[key] or tMeta[key]
			end
		end
	else
		tOri.__index = tMeta
	end

	setmetatable(tOri, tOri)
end

-- 带有属性功能的表
function M.newproperties()
	local t = {}

	local getters =  {}
	local setters = {}

	t.getters = getters

	-- TODO 暂时没有考虑self的问题
	t.__index = function(self, key)
		local getter = getters[key]

		if getter then
			if type(getter) == "table" then
				return getter
			elseif type(getter) == "function" then
				return getter(self, key)
			end
		end
	end

	-- TODO 暂时没有考虑self的问题
	t.__newindex = function(self, key, value)
		local settter = setters[key]
		if settter then
			if type(setter) == "table" then
				return setter
			else
				return setters[key](self, key, value)
			end
		end
	end

	-- 设置对应属性
	function t:setProperty(key, getter, setter)
		getters[key] = getter
		setters[key] = setter
	end

	function t:setTableProperty(key, t1)
		getters[key] = t1
		setters[key] = t1
	end

	local function copyProps(tOri, tDest)
		for k, v in pairs(tOri.getters) do
			local value = tOri[k]
			if type(value) == "table" and value.getters then
				print(value)
				tDest[k] = {}
				copyProps(value, tDest[k])
			else
				print(k, value)
				tDest[k] = value
			end
		end
	end

	-- 此方法主要是给编辑器用的
	function t:properties2json()
		local t1 = {}
		copyProps(self, t1)
		return json.encode(t1)
	end

	setmetatable(t, t)

	return t
end
return M